#define MAX_BUTTON 32

#define YELLOW				0xFFFF00AA

#define BUTTON_DATA_WORLD		(0)
#define BUTTON_DATA_INTERIOR		(1)
#define BUTTON_DATA_TYPE		(2)

#define BUTTON_TYPE_GEN			(0)
#define BUTTON_TYPE_TP			(1)
#define BUTTON_TYPE_NOTE		(2)

#define TogCon(%1,%2) TogglePlayerControllable(%2,false),SetTimerEx("UnFreezePlayer",%1,false,"d",%2)

new
	ButtonData[MAX_BUTTON][1 char],
	ButtonArea[MAX_BUTTON],
	Text3D:ButtonLabel[MAX_BUTTON],
	ButtonString[MAX_BUTTON][128],
	ButtonActive[MAX_BUTTON],
	LinkedButton[MAX_BUTTON];

forward OnButtonPress(playerid, buttonid);
forward UnFreezePlayer(playerid);
public UnFreezePlayer(playerid)TogglePlayerControllable(playerid, true);
// Used so the player doesn't fall through custom maps

stock CreateButton(Float:x, Float:y, Float:z, msg[], world=0, interior=0, type=0, label=0)
{
	new id;
	while(ButtonActive[id])id++;
	if(id>=MAX_BUTTON)return print("BUTTON ID LIMIT REACHED");

	ButtonArea[id]=CreateDynamicSphere(x, y, z, 1.0, world, interior);
	if(label)ButtonLabel[id]=CreateDynamic3DTextLabel(msg, YELLOW, x, y, z, MAX_RENDER_DISTANCE);
	LinkedButton[id]=-1;
	strcat(ButtonString[id], msg);
	ButtonData[id]{BUTTON_DATA_WORLD} = world;
	ButtonData[id]{BUTTON_DATA_INTERIOR} = interior;
	ButtonData[id]{BUTTON_DATA_TYPE} = type;

	ButtonActive[id]=true;

	return id;
}

stock LinkTP(bID1, bID2)
{
    LinkedButton[bID1]=bID2;
    LinkedButton[bID2]=bID1;
}

Internal_OnButtonPress(playerid, buttonid)
{
	if(LinkedButton[buttonid] >= 0)
	{
		new
			id = LinkedButton[buttonid],
			Float:x,
			Float:y,
			Float:z;

		Streamer_GetFloatData(STREAMER_TYPE_AREA, ButtonArea[id], E_STREAMER_X, x);
		Streamer_GetFloatData(STREAMER_TYPE_AREA, ButtonArea[id], E_STREAMER_Y, y);
		Streamer_GetFloatData(STREAMER_TYPE_AREA, ButtonArea[id], E_STREAMER_Z, z);

        TogCon(1000, playerid);
		SetPlayerVirtualWorld(playerid, ButtonData[id]{BUTTON_DATA_WORLD});
		SetPlayerInterior(playerid, ButtonData[id]{BUTTON_DATA_INTERIOR});
		SetPlayerPos(playerid, x, y, z);
		Streamer_UpdateEx(playerid, x, y, z, ButtonData[id]{BUTTON_DATA_WORLD}, ButtonData[id]{BUTTON_DATA_INTERIOR});
	}
	else CallLocalFunction("OnButtonPress", "dd", playerid, buttonid);
	return 1;
}

// Message Box Script
new Text:MsgBox[MAX_PLAYERS];
forward HideMsgBox(playerid);
ShowMsgBox(playerid, message[], time=0)
{
	TextDrawSetString(MsgBox[playerid], message);
	TextDrawShowForPlayer(playerid, MsgBox[playerid]);
	if(time!=0)SetTimerEx("HideMsgBox", time, false, "d", playerid);
}
public HideMsgBox(playerid)TextDrawHideForPlayer(playerid, MsgBox[playerid]);


//


public OnPlayerEnterDynamicArea(playerid, areaid)
{
    for(new x;x<MAX_BUTTON;x++)
	{
		if(areaid==ButtonArea[x])
		{
			ShowMsgBox(playerid, ButtonString[x]);
			break;
		}
	}
	CallLocalFunction("BTN_OnPlayerEnterDynamicArea", "dd", playerid, areaid);
}
#if defined _ALS_OnPlayerEnterDynamicArea
	#undef OnPlayerEnterDynamicArea
#else
	#define _ALS_OnPlayerEnterDynamicArea
#endif
#define OnPlayerEnterDynamicArea BTN_OnPlayerEnterDynamicArea
forward OnPlayerEnterDynamicArea(playerid, areaid);


//


public OnPlayerLeaveDynamicArea(playerid, areaid)
{
    for(new x;x<MAX_BUTTON;x++)
	{
		if(areaid==ButtonArea[x])
		{
			HideMsgBox(playerid);
			break;
		}
	}
	CallLocalFunction("BTN_OnPlayerLeaveDynamicArea", "dd", playerid, areaid);
}
#if defined _ALS_OnPlayerLeaveDynamicArea
	#undef OnPlayerLeaveDynamicArea
#else
	#define _ALS_OnPlayerLeaveDynamicArea
#endif
#define OnPlayerLeaveDynamicArea BTN_OnPlayerLeaveDynamicArea
forward OnPlayerLeaveDynamicArea(playerid, areaid);


//


public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    if(newkeys==16)
	{
		for(new i;i<MAX_BUTTON;i++)
		{
			if(IsPlayerInDynamicArea(playerid, ButtonArea[i]))
			{
				Internal_OnButtonPress(playerid, i);
				break;
			}
		}
	}
	CallLocalFunction("BTN_OnPlayerKeyStateChange", "ddd", playerid, newkeys, oldkeys);
}
#if defined _ALS_OnPlayerKeyStateChange
	#undef OnPlayerKeyStateChange
#else
	#define _ALS_OnPlayerKeyStateChange
#endif
#define OnPlayerKeyStateChange BTN_OnPlayerKeyStateChange
forward OnPlayerKeyStateChange(playerid, newkeys, oldkeys);


public OnGameModeInit()
{
	for(new playerid;playerid<MAX_PLAYERS;playerid++)
	{
		MsgBox[playerid]		=TextDrawCreate(37.000000,130.00000,"_");
		TextDrawUseBox			(MsgBox[playerid],1);
		TextDrawBoxColor		(MsgBox[playerid],0x00000033);
		TextDrawTextSize		(MsgBox[playerid],300,300);
		TextDrawFont			(MsgBox[playerid],1);
		TextDrawLetterSize		(MsgBox[playerid],0.499999,1.600000);
		TextDrawSetShadow		(MsgBox[playerid],0);
	}
	CallLocalFunction("BTN_OnGameModeInit", "");
}
#if defined _ALS_OnGameModeInit
	#undef OnGameModeInit
#else
	#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit BTN_OnGameModeInit
forward OnGameModeInit();
